}
}
- protected function doGet( $key, $flags = 0 ) {
- return $this->unserialize( apc_fetch( $key . self::KEY_SUFFIX ) );
- }
-
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
$casToken = null;
$blob = apc_fetch( $key . self::KEY_SUFFIX );
parent::__construct( $params );
}
- protected function doGet( $key, $flags = 0 ) {
- return $this->unserialize( apcu_fetch( $key . self::KEY_SUFFIX ) );
- }
-
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
$casToken = null;
$blob = apcu_fetch( $key . self::KEY_SUFFIX );
*
* @param string $key
* @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
- * @param int|null $oldFlags [unused]
* @return mixed Returns false on failure or if the item does not exist
*/
- public function get( $key, $flags = 0, $oldFlags = null ) {
- // B/C for ( $key, &$casToken = null, $flags = 0 )
- $flags = is_int( $oldFlags ) ? $oldFlags : $flags;
-
+ public function get( $key, $flags = 0 ) {
$this->trackDuplicateKeys( $key );
return $this->doGet( $key, $flags );
/**
* @param string $key
* @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
+ * @param mixed|null &$casToken Token to use for check-and-set comparisons
* @return mixed Returns false on failure or if the item does not exist
*/
- abstract protected function doGet( $key, $flags = 0 );
-
- /**
- * @note This method is only needed if merge() uses mergeViaCas()
- *
- * @param string $key
- * @param mixed &$casToken
- * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
- * @return mixed Returns false on failure or if the item does not exist
- * @throws Exception
- */
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
- throw new Exception( __METHOD__ . ' not implemented.' );
- }
+ abstract protected function doGet( $key, $flags = 0, &$casToken = null );
/**
* Set an item
$reportDupes = $this->reportDupes;
$this->reportDupes = false;
$casToken = null; // passed by reference
- $currentValue = $this->getWithToken( $key, $casToken, self::READ_LATEST );
+ $currentValue = $this->doGet( $key, self::READ_LATEST, $casToken );
$this->reportDupes = $reportDupes;
if ( $this->getLastError() ) {
}
$curCasToken = null; // passed by reference
- $this->getWithToken( $key, $curCasToken, self::READ_LATEST );
+ $this->doGet( $key, self::READ_LATEST, $curCasToken );
if ( $casToken === $curCasToken ) {
$success = $this->set( $key, $value, $exptime, $flags );
} else {
* up going to the HashBagOStuff used for the in-memory cache).
*
* @ingroup Cache
+ * @TODO: Make this class use composition instead of calling super
*/
class CachedBagOStuff extends HashBagOStuff {
/** @var BagOStuff */
$this->attrMap = $backend->attrMap;
}
- protected function doGet( $key, $flags = 0 ) {
- $ret = parent::doGet( $key, $flags );
+ public function get( $key, $flags = 0 ) {
+ $ret = parent::get( $key, $flags );
if ( $ret === false && !$this->hasKey( $key ) ) {
- $ret = $this->backend->doGet( $key, $flags );
+ $ret = $this->backend->get( $key, $flags );
$this->set( $key, $ret, 0, self::WRITE_CACHE_ONLY );
}
return $ret;
* @ingroup Cache
*/
class EmptyBagOStuff extends BagOStuff {
- protected function doGet( $key, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
+ $casToken = null;
+
return false;
}
}
}
- protected function doGet( $key, $flags = 0 ) {
- if ( !$this->hasKey( $key ) ) {
- return false;
- }
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
+ $casToken = null;
- if ( $this->expire( $key ) ) {
+ if ( !$this->hasKey( $key ) || $this->expire( $key ) ) {
return false;
}
unset( $this->bag[$key] );
$this->bag[$key] = $temp;
- return $this->bag[$key][self::KEY_VAL];
- }
-
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
- $casToken = null;
+ $casToken = $this->bag[$key][self::KEY_CAS];
- $value = $this->doGet( $key );
- if ( $value !== false ) {
- $casToken = $this->bag[$key][self::KEY_CAS];
- }
-
- return $value;
+ return $this->bag[$key][self::KEY_VAL];
}
public function set( $key, $value, $exptime = 0, $flags = 0 ) {
];
}
- protected function doGet( $key, $flags = 0 ) {
- $casToken = null;
-
- return $this->getWithToken( $key, $casToken, $flags );
- }
-
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
return $this->client->get( $this->validateKeyEncoding( $key ), $casToken );
}
return $params;
}
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
$this->debugLog( "get($key)" );
if ( defined( Memcached::class . '::GET_EXTENDED' ) ) { // v3.0.0
$flags = Memcached::GET_EXTENDED;
}
}
- protected function doGet( $key, $flags = 0 ) {
+ public function get( $key, $flags = 0 ) {
if ( ( $flags & self::READ_LATEST ) == self::READ_LATEST ) {
// If the latest write was a delete(), we do NOT want to fallback
// to the other tiers and possibly see the old value. Also, this
public function makeGlobalKey( $class, $component = null ) {
return $this->caches[0]->makeGlobalKey( ...func_get_args() );
}
+
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
+ throw new LogicException( __METHOD__ . ': proxy class does not need this method.' );
+ }
}
$this->client->setLogger( $logger );
}
- protected function doGet( $key, $flags = 0 ) {
- $casToken = null;
-
- return $this->getWithToken( $key, $casToken, $flags );
- }
-
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
$casToken = null;
$req = [
$this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_NONE;
}
- protected function doGet( $key, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
$casToken = null;
- return $this->getWithToken( $key, $casToken, $flags );
- }
-
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
list( $server, $conn ) = $this->getConnection( $key );
if ( !$conn ) {
return false;
$this->readStore->setDebug( $debug );
}
- protected function doGet( $key, $flags = 0 ) {
+ public function get( $key, $flags = 0 ) {
return ( $flags & self::READ_LATEST )
? $this->writeStore->get( $key, $flags )
: $this->readStore->get( $key, $flags );
public function makeGlobalKey( $class, $component = null ) {
return $this->writeStore->makeGlobalKey( ...func_get_args() );
}
+
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
+ throw new LogicException( __METHOD__ . ': proxy class does not need this method.' );
+ }
}
* @ingroup Cache
*/
class WinCacheBagOStuff extends BagOStuff {
- protected function doGet( $key, $flags = 0 ) {
- $blob = wincache_ucache_get( $key );
-
- return is_string( $blob ) ? unserialize( $blob ) : false;
- }
-
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
$casToken = null;
$blob = wincache_ucache_get( $key );
}
$value = unserialize( $blob );
- if ( $value === false ) {
- return false;
+ if ( $value !== false ) {
+ $casToken = (string)$blob; // don't bother hashing this
}
- $casToken = $blob; // don't bother hashing this
-
return $value;
}
}
$curCasToken = null; // passed by reference
- $this->getWithToken( $key, $curCasToken, self::READ_LATEST );
+ $this->doGet( $key, self::READ_LATEST, $curCasToken );
if ( $casToken === $curCasToken ) {
$success = $this->set( $key, $value, $exptime, $flags );
} else {
}
}
- protected function doGet( $key, $flags = 0 ) {
+ protected function doGet( $key, $flags = 0, &$casToken = null ) {
$casToken = null;
- return $this->getWithToken( $key, $casToken, $flags );
- }
+ $blobs = $this->fetchBlobMulti( [ $key ] );
+ if ( array_key_exists( $key, $blobs ) ) {
+ $blob = $blobs[$key];
+ $value = $this->unserialize( $blob );
+
+ $casToken = ( $value !== false ) ? $blob : null;
- protected function getWithToken( $key, &$casToken, $flags = 0 ) {
- $values = $this->getMulti( [ $key ] );
- if ( array_key_exists( $key, $values ) ) {
- $casToken = $values[$key];
- return $values[$key];
+ return $value;
}
+
return false;
}
public function getMulti( array $keys, $flags = 0 ) {
+ $values = [];
+
+ $blobs = $this->fetchBlobMulti( $keys );
+ foreach ( $blobs as $key => $blob ) {
+ $values[$key] = $this->unserialize( $blob );
+ }
+
+ return $values;
+ }
+
+ public function fetchBlobMulti( array $keys, $flags = 0 ) {
$values = []; // array of (key => value)
$keysByTable = [];
if ( $this->isExpired( $db, $row->exptime ) ) { // MISS
$this->debug( "get: key has expired" );
} else { // HIT
- $values[$key] = $this->unserialize( $db->decodeBlob( $row->value ) );
+ $values[$key] = $db->decodeBlob( $row->value );
}
} catch ( DBQueryError $e ) {
$this->handleWriteError( $e, $db, $row->serverIndex );
],
[
'keyname' => $key,
- 'value' => $db->encodeBlob( $this->serialize( $casToken ) )
+ 'value' => $db->encodeBlob( $casToken )
],
__METHOD__
);
/**
* @covers CachedBagOStuff::__construct
- * @covers CachedBagOStuff::doGet
+ * @covers CachedBagOStuff::get
*/
public function testGetFromBackend() {
$backend = new HashBagOStuff;
$cache->set( "key$i", 1 );
$this->assertEquals( 1, $cache->get( "key$i" ) );
$this->assertEquals( 1, $backend->get( "key$i" ) );
+
$cache->delete( "key$i" );
$this->assertEquals( false, $cache->get( "key$i" ) );
$this->assertEquals( false, $backend->get( "key$i" ) );
}
/**
- * @covers CachedBagOStuff::doGet
+ * @covers CachedBagOStuff::get
*/
public function testCacheBackendMisses() {
$backend = new HashBagOStuff;